package com.zzx.auth.oauth2;

import com.zzx.auth.biz.SysMenuBiz;
import com.zzx.auth.biz.SysRoleBiz;
import com.zzx.auth.biz.SysUserBiz;
import com.zzx.auth.model.SysUser;
import com.zzx.auth.model.dto.UserInfo;
import com.zzx.common.enums.SysUserStatusEnum;
import com.zzx.common.enums.UserTypeEnum;
import com.zzx.common.exception.CommonException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 自定义校验用户和获取认证的权限名
 */
@Service
@Slf4j
public class UserDetailServiceImpl implements UserDetailsService {

    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private SysUserBiz sysUserBiz;
    @Autowired
    private SysRoleBiz sysRoleBiz;
    @Autowired
    private SysMenuBiz sysMenuBiz;

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        System.out.println("开始校验用户" + LocalDateTime.now());
        //获取用户信息
        UserInfo data = getUserInfo(userName);
        //校验用户状态和绑定集团状态
        checkUser(data, userName);
        checkRole(data, userName);
        Set<String> dbAuthsSet = new HashSet<String>();
        /*if (CollectionCheckUtil.checkSetIsNotEmpty(data.getRoles())) {
            // 获取角色菜单权限
            dbAuthsSet.addAll(data.getRoles());
        }
        if (CollectionCheckUtil.checkSetIsNotEmpty(data.getPermissions())) {
            // 获取用户角色权限
            dbAuthsSet.addAll(data.getPermissions());
        }
        */
        Collection<? extends GrantedAuthority> authorities = AuthorityUtils
                .createAuthorityList(new String[0]);
        SysUser sysUser = data.getSysUser();
        Set<String> perms = data.getPermissions();
        perms.addAll(data.getRoles());
        redisTemplate.opsForSet().add("login:perms:user:" + sysUser.getUserId(), perms.toArray(new String[perms.size()]));
        redisTemplate.expire("login:perms:user:" + sysUser.getUserId(), 24, TimeUnit.HOURS);
        // 普通门店
        System.out.println("校验用户完毕" + LocalDateTime.now());
        return new LoginUser(sysUser,authorities);
    }

    /**
     * 校验权限/校验角色
     */
    public void checkRole(UserInfo userResult, String userName) {
        Set<String> roles = userResult.getRoles();
        if (CollectionUtils.isEmpty(roles))
            throw new CommonException(500, "对不起，您的账号：" + userName + ",没有绑定角色!");
        Set<String> permissions = userResult.getPermissions();
        if (userResult.getSysUser().getUserType() != UserTypeEnum.SUPER_ADMIN.getType() && CollectionUtils.isEmpty(permissions))
            throw new CommonException(500, "对不起，您的账号：" + userName + ",没有菜单权限!");
    }

    /**
     * 检查用户信息
     */
    public void checkUser(UserInfo userResult, String userName) {
        if (userResult == null)
            throw new CommonException(500, "系统异常,请稍后重试...");
        SysUser sysUser = userResult.getSysUser();
        //判断用户是否存在
        if (sysUser == null)
            throw new UsernameNotFoundException("用户名 " + userName + " 不存在!");
        Integer userStatus = sysUser.getStatus();
        if (userStatus!=null&&userStatus.equals(SysUserStatusEnum.DISABLE.getCode())) {
            throw new CommonException(500, "您的账号：" + userName + ",已被禁用, 请联系集团管理人员");
        }
        //判断用户是否删除
        boolean delFlag = sysUser.getDelFlag();
        if (delFlag)
            throw new CommonException(500, "对不起，您的账号：" + userName + ",已被删除!");
        //判断用户是否拉黑
        if (SysUserStatusEnum.BLOCK.getCode() == userStatus)
            throw new CommonException(500, "对不起，您的账号：" + userName + ",已被拉黑!");

    }

    public UserInfo getUserInfo(String userName) {
        UserInfo userInfo = new UserInfo();
        //获取用户信息
        SysUser oneByUserName = getOneByUserNameNoPassWord(userName);
        userInfo.setSysUser(oneByUserName);
        //获取用户角色信息
        Set<String> roleKeysByUserName = sysRoleBiz.selectRoleKeysByUserName(userName);
        userInfo.setRoles(roleKeysByUserName);
        //获取用户资源信息
        Set<String> menuPermsByUserName = sysMenuBiz.getMenuPermsByUserName(userName);
        userInfo.setPermissions(menuPermsByUserName);
        return userInfo;
    }

    public SysUser getOneByUserNameNoPassWord(String userName) {
        return sysUserBiz.selectUserByUserName(userName);
    }

}
